%option noyywrap
%x COMMENT_STATE

%{
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include "parser.tab.hpp"
#include "ast.h"

using namespace ast;
using std::string;

%}

DIGIT     [0-9]
ID        [a-zA-Z_][a-zA-Z0-9_]*
WHITESPACE [ \t\r\n]

%%

"//" { 
    int c;
    while ((c = yyinput()) != EOF) {
        if (c == '\n' || c == '\r') {
            if (c == '\r' && (c = yyinput()) != '\n' && c != EOF) 
                unput(c);
            break;
        }
    }
    BEGIN(INITIAL);
}

"/*" { BEGIN(COMMENT_STATE); }

<COMMENT_STATE>{
    "*/"      {  BEGIN(INITIAL); }
    [^*]     { }     
    [*]       { }        
    \n        {}    
    <<EOF>>   { 
        fprintf(stderr, "Error: Unterminated comment\n"); 
    }
}

"int"       { return INT; }
"void"      { return VOID; }
"if"        { return IF; }
"else"      { return ELSE; }
"while"     { return WHILE; }
"break"     { return BREAK; }
"continue"  { return CONTINUE; }
"return"    { return RETURN; }


"="         { return ASSIGN; }
"||"        { return OR; }
"&&"        { return AND; }
"<"         { return LT; }
">"         { return GT; }
"<="        { return LE; }
">="        { return GE; }
"=="        { return EQ; }
"!="        { return NE; }
"+"         { return PLUS; }
"-"         { return MINUS; }
"*"         { return TIMES; }
"/"         { return DIV; }
"%"         { return MOD; }
"!"         { return NOT; }
","         { return COMMA; }
";"         { return SEMICOLON; }
"("         { return LPAREN; }
")"         { return RPAREN; }
"{"         { return LBRACE; }
"}"         { return RBRACE; }


{ID}        { 
                yylval.str_val = new string(yytext); 
                return ID; 
            }
{DIGIT}+    { 
                yylval.int_val = atoi(yytext); 
                return NUM; 
            }

{WHITESPACE}+ ;  

%%


